package cn.itcast.web;

import cn.itcast.mapper.horsemanMapper;
import cn.itcast.mapper.orderMapper;
import cn.itcast.pojo.*;
import cn.itcast.service.impl.PayServiceImpl;
import cn.itcast.service.impl.orderServiceImpl;
import cn.itcast.util.OutputStringController;
import cn.wx.MyConfig;
import cn.wx.WXPay;
import cn.wx.WXPayUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @Description: ${微信支付}
 * @return ${return_type}
 * @throws
 * @author 欧阳辉
 * @date 2020/3/16 16:57
 */

@Slf4j
@RestController
@RequestMapping(value="/wxshop/user",produces="text/html;charset=UTF-8")
public class Wxpay {

    @Autowired
    private StringRedisTemplate template;



    @Resource
    orderServiceImpl orderService;

    @Resource
    PayServiceImpl payService;
    @Resource
    OutputStringController osc;

    @Resource
    private horsemanMapper horsemanMapper;


    @Resource
    private orderMapper orderMapper;

    private Integer orderId;

    private boolean isHorsemanRecharge=false;

    private int tempTotal_fee;


    /**
     *
     * @Description:
     * 微信统一下单接口
     * @auther: 欧阳辉
     * @date: 8:12 2020/3/17
     * @param: [request]
     * @return: java.lang.String
     *
     */
    @RequestMapping(value = "/doUnifiedOrder", method = RequestMethod.POST)
    public String doUnifiedOrder(@RequestBody Map<String,String> map) {
        //返回结果
        String results="";
        Map resultMap=new HashMap();
        String openid = map.get("openId");
        String name = map.get("name");
        int total_fee = Integer.parseInt(map.get("totalFee"));
        tempTotal_fee=total_fee;

//        List<horseman> horsemen = horsemanMapper.selectHorsemanOpenId(openid);
//        if (!horsemen.isEmpty()||horsemen.size()>0){
//            List<order> orders = orderMapper.selectHorsemanStocksOrder(horsemen.get(0).getOpenId());
//            orderId=orders.get(0).getId();
//            isHorsemanRecharge=true;
//        }


        log.debug(openid);
        MyConfig config = null;
        WXPay wxpay =null;
        try {
            config = new MyConfig();
            wxpay= new WXPay(config);
        } catch (Exception e) {
            e.printStackTrace();
        }
        //生成的随机字符串
        String nonce_str = WXPayUtil.generateNonceStr();
        //获取客户端的ip地址
        //获取本机的ip地址
        InetAddress addr = null;
        try {
            addr = InetAddress.getLocalHost();
        } catch (UnknownHostException e) {
            e.printStackTrace();
        }
        String spbill_create_ip = addr.getHostAddress();
        //支付金额，需要转成字符串类型，否则后面的签名会失败
        //int  total_fee=1;
        //商品描述
        String body = "环保金充值";
        //商户订单号
        //String out_trade_no = getOrderIdByTime();
        String out_trade_no= WXPayUtil.generateNonceStr();
        //统一下单接口参数timeStamp
        HashMap<String, String> data = new HashMap<String, String>();
        data.put("appid", "wx1cf12dee9dbfe13c");
        data.put("mch_id", "1550181801");
        data.put("nonce_str", nonce_str);
        data.put("body", body);
        data.put("out_trade_no",out_trade_no);
        data.put("total_fee", String.valueOf(total_fee));
        data.put("spbill_create_ip", spbill_create_ip);
        data.put("notify_url", "https://www.dhnep.cn:443/wxshop/user/notify");
        data.put("trade_type","JSAPI");
        data.put("openid", openid);
        try {
            Map<String, String> rMap = wxpay.unifiedOrder(data);
            System.out.println("统一下单接口返回: " + rMap);

            //生成业务充值记录订单
            recharge recharge = new recharge();
            recharge.setOpenId(openid);
            recharge.setName(name);
            recharge.setRechargeTime(new Date());
            recharge.setRechargeSum(Double.valueOf(total_fee)/100);
            recharge.setRechargeNumber(out_trade_no);
            recharge.setPayNumber(rMap.get("prepay_id"));
            recharge.setPayType("微信支付");
            recharge.setPayState("未支付");
            recharge.setBillState("未入账");

            orderService.addRecharge(recharge);




            String return_code = (String) rMap.get("return_code");
            String result_code = (String) rMap.get("result_code");
            String nonceStr = WXPayUtil.generateNonceStr();
            resultMap.put("nonceStr", nonceStr);
            Long timeStamp = System.currentTimeMillis() / 1000;
            if ("SUCCESS".equals(return_code) && return_code.equals(result_code)) {
                String prepayid = rMap.get("prepay_id");
                resultMap.put("package", "prepay_id="+prepayid);
                resultMap.put("signType", "MD5");
                //这边要将返回的时间戳转化成字符串，不然小程序端调用wx.requestPayment方法会报签名错误
                resultMap.put("timeStamp", timeStamp + "");
                //再次签名，这个签名用于小程序端调用wx.requesetPayment方法
                resultMap.put("appId","wx1cf12dee9dbfe13c");
                log.debug(resultMap.toString());
                String sign = WXPayUtil.generateSignature(resultMap, "0B2DC615EA4F78BC4B216AEA1A6DA63B");
                resultMap.put("paySign", sign);
                log.debug("生成的签名paySign : "+ sign);
                results = osc.resultSuccess("yes",resultMap);
                return results;
            }else{
                return  results;
            }
        } catch (Exception e) {
            e.printStackTrace();
            return  results;
        }
    }


    /**
     *微信支付回调
     */
    @RequestMapping("notify")
    public String notifynotify(HttpServletRequest request) {
        log.info("================================================开始处理微信小程序发送的异步通知");

        //1 获取微信支付异步回调结果
        String xmlResult = WXPayUtil.getPostStr(request);

        Map<String, String> resultMap = null;
        try {
            //将结果转成map
            resultMap = WXPayUtil.xmlToMap(xmlResult);
        } catch (Exception e1) {
            e1.printStackTrace();
        }
        //订单号
        String orderNo = resultMap.get("out_trade_no");
        log.info("订单号：------------------"+orderNo+"结束----------");
        String result_code = resultMap.get("result_code");
        //回调返回的加密签名 保存下来 下面会进行对比
        String sign = resultMap.get("sign");
        //去掉sign和利用微信回调回来的信息重新加密
        resultMap.remove("sign");
        String sign1="";
        try {
            //重新加密 获取加密的签名
            sign1=WXPayUtil.generateSignature(resultMap, "0B2DC615EA4F78BC4B216AEA1A6DA63B"); //签名
        }catch (Exception e){

        }


        String resultCode;
        String resultMsg;
        //对比微信回调的加密与重新加密是否一致  一致即为通过 不一致说明呗改动过 加密不通过
        log.info("==============================================开始对比加密++++++++++++++++++++++++++++++++++++++");
        if (sign.equals(sign1)) { //验签通过
            log.info("==============================================验签通过++++++++++++++++++++++++++++++++++++++");
            log.info(result_code);
            if (result_code.equals("SUCCESS")) {//业务结果为SUCCESS
                /**
                 * 这里写你要处理的逻辑
                 */
                //修改订单状态,增加账户金额
                recharge recharge = new recharge();
                recharge.setPayState("已支付");
                recharge.setBillState("已入账");
                recharge.setBillTime(new Date());
                recharge.setRechargeNumber(orderNo);

                boolean isupdate = orderService.updateRecharge(recharge);

//                记录骑手充值记录到核对表中
//                if (isHorsemanRecharge){
//                    WithdrawRechargeInfo withdrawRechargeInfo = new WithdrawRechargeInfo();
//                    withdrawRechargeInfo.setOrderId(orderId);
//                    withdrawRechargeInfo.setRechargeMoney(Integer.valueOf(tempTotal_fee).longValue());
//                    withdrawRechargeInfo.setRechargeNumber(orderNo);
//                    withdrawRechargeInfo.setWithdrawTime(new Date());
//                    withdrawRechargeInfo.setRechargeTime(new Date());
//                    withdrawRechargeInfoMapper.insertSelective(withdrawRechargeInfo);
//                }

                resultCode = "SUCCESS";
                resultMsg = "成功";
            } else { // 业务结果为FALL
                resultCode = "FAIL";
                resultMsg = "业务结果为FAIL";
            }

        } else {
            resultCode = "FAIL";
            resultMsg = "验签未通过";
        }

        Map<String, String> returnMap = new HashMap<>();
        returnMap.put("return_code", resultCode);
        returnMap.put("return_msg", resultMsg);
        try {
            String s = WXPayUtil.mapToXml(returnMap);
            return s;
        } catch (Exception e) {
            e.printStackTrace();
            return "";
        }
    }




    /**
     *
     * @Description:
     * 骑手提现入口
     * @auther: 欧阳辉
     * @date: 8:12 2020/3/17
     * @param: [request]
     * @return: java.lang.String
     *
     */
    @RequestMapping(value = "/cash", method = RequestMethod.POST)
    public String cash(HttpServletRequest request,@RequestBody Map<String,String> map) {
        //返回结果
        String results = "";
        Map resultMap = new HashMap();
        String openid = map.get("openId");
        String amount = map.get("amount");
        log.debug("骑手提现开始");

        //try {
            horseman horseman = payService.queryByOpenId(openid);
            if (null == horseman) {
                results = osc.failure("no");
                return results;
            }
            //校验
            account account = payService.queryAccountByOpenId(openid);
            if (null != account) {
                if (account.getAccountMoneyBalance().compareTo(Double.valueOf(amount)) == -1) {//余额小于提现金额
                    results = osc.failure("余额不足");
                    return results;
                }
            } else {
                results = osc.failure("该账户不存在");
                return results;
            }


//            //获取请求ip地址
//            String ip = request.getHeader("x-forwarded-for");
//
//            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
//                ip = request.getHeader("Proxy-Client-IP");
//            }
//            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
//                ip = request.getHeader("WL-Proxy-Client-IP");
//            }
//            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
//                ip = request.getRemoteAddr();
//            }
//            if (ip.indexOf(",") != -1) {
//                String[] ips = ip.split(",");
//                ip = ips[0].trim();
//            }
//
//
//            MyConfig config = null;
//            WXPay wxpay = null;
//            try {
//                config = new MyConfig();
//                wxpay = new WXPay(config);
//            } catch (Exception e) {
//                e.printStackTrace();
//            }
//            //生成的随机字符串
//            String nonce_str = WXPayUtil.generateNonceStr();
//            //获取客户端的ip地址
//            //获取本机的ip地址
//            InetAddress addr = null;
//            try {
//                addr = InetAddress.getLocalHost();
//            } catch (UnknownHostException e) {
//                e.printStackTrace();
//            }
//            String spbill_create_ip = addr.getHostAddress();
//            //支付金额，需要转成字符串类型，否则后面的签名会失败
//            //int  total_fee=1;
//            String money = new BigDecimal(amount).multiply(new BigDecimal(100)).setScale(0, BigDecimal.ROUND_DOWN).toString();
//            log.debug("提现金额"+money);
//            //商品描述
//            String body = "环保金提现";
            //商户订单号
            String out_trade_no = getOrderIdByTime()+"UID"+horseman.getHorsemanId();
            //String out_trade_no = WXPayUtil.generateNonceStr();
            //统一下单接口参数
//            HashMap<String, String> data = new HashMap<String, String>();
//            data.put("mch_appid", "wx1cf12dee9dbfe13c");
//            data.put("mchid", "1563820051");
//            data.put("nonce_str", nonce_str);
//            data.put("desc", body);
//            data.put("partner_trade_no", out_trade_no);
//            data.put("openid", openid);
//            data.put("check_name", "NO_CHECK");
//            data.put("amount", money);
//            data.put("spbill_create_ip", ip);
////            data.put("notify_url", "https://www.vaiq.cn:443/wxshop/user/notify");
////            data.put("trade_type", "JSAPI");
////            data.put("openid", openid);
//            //String sign = WXPayUtil.generateSignature(paraMap, WXPayConstants.PATERNER_KEY);//微信公众号开发者密码
//            String sign = WXPayUtil.generateSignature(data, "0B2DC615EA4F78BC4B216AEA1A6DA63B");//商户密码
//            data.put("sign", sign);
//            String xml = WXPayUtil.mapToXml(data);//将所有参数(map)转xml格式

            //创建提现记录
            withdraw withdraw = new withdraw();
            withdraw.setOpenId(openid);
            withdraw.setNumber(out_trade_no);
            withdraw.setName(horseman.getNickName());
            withdraw.setPhone(horseman.getHorsemanPhone());
            withdraw.setApplyTime(new Date());
            withdraw.setUserType("0");
            withdraw.setType("微信提现");
            withdraw.setNum(Double.valueOf(amount));
            withdraw.setState("已申请");
            withdraw.setTransfer(new Date());

            withdraw withdraws = payService.createWithDraw(withdraw,"骑手");
            if(withdraws!=null){
                log.debug("创建提现记录成功");
                results = osc.success("创建提现记录成功");
            }else {
                log.debug("创建提现记录失败");
                results = osc.failure("创建提现记录失败");
            }



            //企业付款
//            String macPayUrl = "https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers";
////
//////            String xmlStr = HttpClientUtil.sendPost(macPayUrl, xml);
////            String xmlStr = HttpClientUtil.posts(macPayUrl, xml);
////
////            Map<String, String> reMap = WXPayUtil.xmlToMap(xmlStr);
////            log.debug(reMap.toString());
////            if (CollectionUtil.isNotEmpty(reMap) && "SUCCESS".equals(reMap.get("result_code"))) {
////                //成功需要进行的逻辑操作
////                log.debug("提现成功");
////
////                //修改骑手账户金额
////                boolean isUpdate = payService.updateHoresmanAccount(account,Double.parseDouble(amount),withdraw);
////                if(isUpdate){
////                    results = osc.success("提现成功");
////                }else {
////                    results = osc.failure("提现成功,账户金额修改失败");
////                }
////
////
////            }else {
////                if (CollectionUtil.isNotEmpty(reMap)) {
////                    //resMap.put("msg","提现失败:"+reMap.get("err_code") + ":" + reMap.get("err_code_des"));
////                    log.debug("提现失败");
////                    results = osc.failure("提现失败");
////                }
////                //resMap.put("code",0);
////            }
////
////        } catch (Exception e) {
////            e.printStackTrace();
////            results = osc.failure("提现失败");
////        }
        return results;
    }



    /**
     *
     * @Description:
     * 用户提现入口
     * @auther: 欧阳辉
     * @date: 8:12 2020/3/17
     * @param: [request]
     * @return: java.lang.String
     *
     */
    @RequestMapping(value = "/cashUser", method = RequestMethod.POST)
    public String cashUser(HttpServletRequest request,@RequestBody Map<String,String> map) {
        //返回结果
        String results = "";
        Map resultMap = new HashMap();
        String openid = map.get("openId");
        String amount = map.get("amount");
        log.debug("用户提现开始");

            user user = payService.queryByUserOpenId(openid);
            if (null == user) {
                results = osc.failure("no");
                return results;
            }
            //校验
            account account = payService.queryAccountByOpenIdByUser(openid);
            if (null != account) {
                if (account.getAccountMoneyBalance().compareTo(Double.valueOf(amount)) == -1) {//余额小于提现金额
                    results = osc.failure("余额不足");
                    return results;
                }
            } else {
                results = osc.failure("该账户不存在");
                return results;
            }

            //商户订单号
            String out_trade_no = getOrderIdByTime()+"UID"+user.getUserWxid();





            //创建提现记录
            withdraw withdraw = new withdraw();
            withdraw.setOpenId(openid);
            withdraw.setNumber(out_trade_no);
            withdraw.setName(user.getNickName());
            withdraw.setPhone(user.getUserPhone());
            withdraw.setApplyTime(new Date());
            withdraw.setUserType("1");
            withdraw.setType("微信提现");
            withdraw.setNum(Double.valueOf(amount));
            withdraw.setState("已申请");
            withdraw.setTransfer(new Date());

            withdraw withdraws = payService.createWithDraw(withdraw,"用户");
            if(withdraws!=null){


                log.debug("创建提现记录成功");
                return osc.success("创建提现记录成功");
            }else {
                log.debug("创建提现记录失败");
                return osc.failure("创建提现记录失败");
            }




    }



        /**
         *
         * @Description:
         * 随机生成订单号
         * @auther: 欧阳辉
         * @date: 8:23 2020/3/17
         * @param: []
         * @return: java.lang.String
         *
         */
        public String getOrderIdByTime() {
            SimpleDateFormat sdf=new SimpleDateFormat("yyyyMMddHHmmss");
            String newDate=sdf.format(new Date());
            String result="";
            Random random=new Random();
            for(int i=0;i<3;i++){
                result+=random.nextInt(10);
            }
            return newDate+result;
        }





}